using System;
using System.Collections.Generic;
using System.Text;

namespace TagTool.Devices.Midi
{
    public class MidiManager : IDeviceManager
    {
        private IList<IMidiDevice> inputDeviceList;
        private IList<IMidiDevice> outputDeviceList;

        private static MidiManager instance = new MidiManager();
        
        public static MidiManager Instance
        {
        	get { return instance; }
        }
        
        private MidiManager()
        {
        	
            inputDeviceList = new List<IMidiDevice>();
            for(uint i = 0; i < NumOfInDevices; i++)
            {
            	inputDeviceList.Add(new MidiInputDevice(i));
            }
            outputDeviceList = new List<IMidiDevice>();
            for(uint i = 0; i < NumOfOutDevices; i++)
            {
            	outputDeviceList.Add(new MidiOutputDevice(i));
            }            
        }

        #region Properties

        public int NumberOfDevices
        {
            get
            {
                return NumOfInDevices + NumOfOutDevices;
            }
        }

        public int NumOfInDevices
        {
            get
            {
				return (int)WinMidi.MidiInGetNumDevs();
            }
        }

        public int NumOfOutDevices
        {
            get
            {
            	return (int)WinMidi.MidiOutGetNumDevs();
            }
        }

        #endregion Properties

        #region Methods

        public void AddDevice(IDevice midi)
        {
            if ((midi != null) && (midi is IMidiDevice))
            {
                if (((IMidiDevice)midi).Type == MidiDeviceType.Input)
                {
                    AddInputDevice((IMidiDevice)midi);
                }
                else if (((IMidiDevice)midi).Type == MidiDeviceType.Output)
                {
                    AddOutputDevice((IMidiDevice)midi);
                }
            }
        }

        public void RemoveDevice(IDevice midi)
        {
            if ((midi != null) && (midi is IMidiDevice))
            {
                if (((IMidiDevice)midi).Type == MidiDeviceType.Input)
                {
                    RemoveInputDevice((IMidiDevice)midi);
                }
                else if (((IMidiDevice)midi).Type == MidiDeviceType.Output)
                {
                    RemoveOutputDevice((IMidiDevice)midi);
                }
            }
        }

        private void AddInputDevice(IMidiDevice midi)
        {
                inputDeviceList.Add(midi);
        }

        private void RemoveInputDevice(IMidiDevice midi)
        {
            inputDeviceList.Remove(midi);
        }

        private void AddOutputDevice(IMidiDevice midi)
        {
            outputDeviceList.Add(midi);
        }

        private void RemoveOutputDevice(IMidiDevice midi)
        {
            outputDeviceList.Remove(midi);
        }

        public IDevice GetDevice(int index)
        {
            IMidiDevice device = null;
            if ((index >= 0) && (index < inputDeviceList.Count))
            {
                device = inputDeviceList[index];
            }
            return device;
        }

        public IDevice GetDevice(string name)
        {
            foreach (IMidiDevice device in inputDeviceList)
            {
                if (device.Name.Equals(name))
                {
                    return device;
                }
            }
            return null;
        }

        #endregion Methods
    }
}
